﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using VietImage.Helpers;

namespace VietImage.Models
{
    public partial class User
    {
        #region Properties
        public Permission Permission
        {
            get
            {
                return this.GetPermission();
            }
        }

        public City City
        {
            get
            {
                return this.GetCity();
            }
        }

        public Status Status
        {
            get
            {
                return this.GetStatus();
            }
        }

        public List<DetailUser> Details
        {
            get
            {
                return GetDetails();
            }
        }
        #endregion

        #region Methods

        public User(int id, String username, String password, DateTime createdTime, int id_Status, DateTime birthDay, int id_City, String email, String cellfone, int gender, int id_Permission)
        {
            this.ID = id;
            this.Username = username;
            this.Password = password;
            this.CreatedTime = createdTime;
            this.ID_Status = id_Status;
            this.Birthday = birthDay;
            this.ID_City = id_City;
            this.Email = email;
            this.Cellfone = cellfone;
            this.Gender = gender;
            this.ID_Permission = id_Permission;
        }

        public User Clone()
        {
            User u = new User(this.ID, this.Username, this.Password, this.CreatedTime, this.ID_Status, this.Birthday.Value, this.ID_City.Value, this.Email, this.Cellfone, this.Gender.Value, this.ID_Permission);
            return u;
        }

        public DetailUser GetDetail(int lang)
        {
            VietImageDataClassesDataContext _db = new VietImageDataClassesDataContext();
            var v = _db.DetailUsers.Where(p => p.ID_User == this.ID && p.ID_Language == lang);
            if (v.Count() == 0)
                return null;
            return v.First();
        }

        public List<DetailUser> GetDetails()
        {
            VietImageDataClassesDataContext _db = new VietImageDataClassesDataContext();
            var v = _db.DetailUsers.Where(p => p.ID_User == this.ID);
            if (v.Count() == 0)
                return null;
            return v.ToList();
        }

        public Permission GetPermission()
        {
            VietImageDataClassesDataContext _db = new VietImageDataClassesDataContext();
            var v = _db.Permissions.Where(p => p.ID == this.ID_Permission);
            if (v.Count() == 0)
                return null;
            return v.First();
        }

        public City GetCity()
        {
            VietImageDataClassesDataContext _db = new VietImageDataClassesDataContext();
            var v = _db.Cities.Where(p => p.ID == this.ID_City);
            if (v.Count() == 0)
                return null;
            return v.First();
        }

        public Status GetStatus()
        {
            VietImageDataClassesDataContext _db = new VietImageDataClassesDataContext();
            var v = _db.Status.Where(p => p.ID == this.ID_Status);
            if (v.Count() == 0)
                return null;
            return v.First();
        }
        #endregion

        #region Static Methods
        public static User Parse(System.Object value)
        {
            User temp = null;
            try
            {
                temp = (User)value;
            }
            catch (Exception ex)
            {
            }
            return temp;
        }

        public static List<User> GetPartner()
        {
            VietImageDataClassesDataContext _db = new VietImageDataClassesDataContext();
            var v = _db.Users.Where(p => p.ID_Status != 2 && p.ID_Permission == 4);
            if (v.Count() == 0)
                return null;
            return v.ToList();
        }

        public static List<User> GetCustomer()
        {
            VietImageDataClassesDataContext _db = new VietImageDataClassesDataContext();
            var v = _db.Users.Where(p => p.ID_Status != 2 && p.ID_Permission == 5);
            if (v.Count() == 0)
                return null;
            return v.ToList();
        }

        public static User GetUser(String username, String password)
        {
            VietImageDataClassesDataContext _db = new VietImageDataClassesDataContext();
            var i = _db.Users.Where(p => p.Username == username && p.Password == Encoder.MD5Encode(password));
            if (i.ToList().Count == 0)
                return null;
            return i.First();
        }

        public static User GetUser(int id)
        {
            VietImageDataClassesDataContext _db = new VietImageDataClassesDataContext();
            var i = _db.Users.Where(p => p.ID == id);
            if (i.ToList().Count == 0)
                return null;
            return i.First();
        }

        public static List<User> GetListAvailable()
        {
            VietImageDataClassesDataContext _db = new VietImageDataClassesDataContext();
            var v = _db.Users.Where(p => p.ID_Status != 2);
            if (v.Count() == 0)
                return null;
            return v.ToList();
        }

        public static List<User> GetListNotAvailable()
        {
            VietImageDataClassesDataContext _db = new VietImageDataClassesDataContext();
            var v = _db.Users.Where(p => p.ID_Status == 2);
            if (v.Count() == 0)
                return null;
            return v.ToList();
        }

        public static User ValidationUser(String username, String password)
        {
            User u = new User();
            u = User.GetUser(username, password);
            return u;
        }

        public static List<User> GetList()
        {
            VietImageDataClassesDataContext _db = new VietImageDataClassesDataContext();
            var v = _db.Users.OrderByDescending(p => p.ID);
            if (v.Count() == 0)
                return null;
            return v.ToList();
        }

        private static List<ErrorItem> InputInfomationValidation(User user)
        {
            List<ErrorItem> errorList = new List<ErrorItem>();
            if (user.Username == "")
                errorList.Add(new ErrorItem("Username", "Username is required"));
            if (user.Username.Length > 50)
                errorList.Add(new ErrorItem("Username", "Username is only allow up to 50 characters."));
            if (user.Password == "")
                errorList.Add(new ErrorItem("Password", "Password is required"));
            if (user.Password.Length > 50)
                errorList.Add(new ErrorItem("Password", "Password is only allow up to 50 characters."));
            if (user.Email.Length > 100)
                errorList.Add(new ErrorItem("Email", "Email is only allow up to 100 characters."));
            if (user.Cellfone.Length > 20)
                errorList.Add(new ErrorItem("Cellfone", "Cellfone is only allow up to 20 characters."));
            return errorList;
        }

        public static List<ErrorItem> Insert(ref User ii, int id_User, int id_Lang)
        {
            VietImageDataClassesDataContext _db = new VietImageDataClassesDataContext();
            List<ErrorItem> errorList = InputInfomationValidation(ii);
            if (errorList.Count == 0)
            {
                Nullable<Int32> id = null;
                Nullable<Int32> id_au = id_User;
                int errorMess = _db.InsertUser(ref id, ii.Username, Encoder.MD5Encode(ii.Password), ii.Birthday, ii.ID_City, ii.Email, ii.Cellfone, ii.Gender, ii.ID_Permission, id_au);
                if (errorMess == 1)
                    ii.ID = id.Value;
                
                if(errorMess != 1) errorList.Add(new ErrorItem("ErrorMessage", _db.ErrorMessages.Single(p => p.ID_ErrorMessage == errorMess && p.ID_Language == id_Lang).Description));
            }
            return errorList;
        }

        public static List<ErrorItem> ChangeInformation(User ic, int id_User, int id_Lang)
        {
            VietImageDataClassesDataContext _db = new VietImageDataClassesDataContext();
            List<ErrorItem> errorList = InputInfomationValidation(ic);
            if (errorList.Count == 0)
            {
                User oi = _db.Users.Single(p => p.ID == ic.ID);
                String content = "";
                content = oi.Username + "_" + oi.Password + "_" + oi.ID_Status + "_" + oi.Birthday + "_" + oi.ID_City + "_" + oi.Email + "_" + oi.Cellfone + "_" + oi.Gender + "_" + oi.Permission;
                int errorMess = _db.ChangeUser(ic.ID, id_User, ic.ID_City, ic.ID_Status, ic.Username, ic.Password, ic.Birthday, ic.Email, ic.Cellfone, ic.Gender, ic.ID_Permission, content, 0, 0);

                if(errorMess != 1) errorList.Add(new ErrorItem("ErrorMessage", _db.ErrorMessages.Single(p => p.ID_ErrorMessage == errorMess && p.ID_Language == id_Lang).Description));
            }
            return errorList;
        }

        public static List<ErrorItem> ChangeInformation(User ic, int id_User, int id_Log, int id_Lang)
        {
            VietImageDataClassesDataContext _db = new VietImageDataClassesDataContext();
            List<ErrorItem> errorList = InputInfomationValidation(ic);
            if (errorList.Count == 0)
            {
                User oi = _db.Users.Single(p => p.ID == ic.ID);
                String content = "";
                content = oi.Username + "_" + oi.Password + "_" + oi.ID_Status + "_" + oi.Birthday + "_" + oi.ID_City + "_" + oi.Email + "_" + oi.Cellfone + "_" + oi.Gender + "_" + oi.Permission;
                int errorMess = _db.ChangeUser(ic.ID, id_User, ic.ID_City, ic.ID_Status, ic.Username, ic.Password, ic.Birthday, ic.Email, ic.Cellfone, ic.Gender, ic.ID_Permission, content, id_Log, 1);

                if(errorMess != 1) errorList.Add(new ErrorItem("ErrorMessage", _db.ErrorMessages.Single(p => p.ID_ErrorMessage == errorMess && p.ID_Language == id_Lang).Description));
            }
            return errorList;
        }

        public static List<ErrorItem> Delete(int id_PassiveUser, int id_ActiveUser, int deep, int id_Lang)
        {
            List<ErrorItem> errorList = new List<ErrorItem>();
            VietImageDataClassesDataContext _db = new VietImageDataClassesDataContext();

            int errorMess = _db.DeleteUser(id_ActiveUser, id_PassiveUser, deep);
            
                if(errorMess != 1) errorList.Add(new ErrorItem("ErrorMessage", _db.ErrorMessages.Single(p => p.ID_ErrorMessage == errorMess && p.ID_Language == id_Lang).Description));


            return errorList;
        }
        #endregion

        #region Search
        private static String BuildQuery(Dictionary<String, System.Object> parametersList, Dictionary<String, bool> exactList)
        {
            String query = "";

            DateTime noValue = new DateTime(2000, 1, 1);

            foreach (KeyValuePair<String, System.Object> kvp in parametersList)
            {
                if (query.Length != 0)
                    query += " AND ";
                if (kvp.Key == "ID" || kvp.Key == "ID_Status" || kvp.Key == "ID_Permission" || kvp.Key == "ID_City")
                {
                    if (int.Parse(kvp.Value.ToString()) >= 1)
                        query += kvp.Key + " = " + int.Parse(kvp.Value.ToString());
                }
                else if (kvp.Key == "Gender")
                {
                    if (int.Parse(kvp.Value.ToString()) == 1 || int.Parse(kvp.Value.ToString()) == 0)
                        query += kvp.Key + " = " + int.Parse(kvp.Value.ToString());
                }
                else if (kvp.Key == "Username" || kvp.Key == "Email" || kvp.Key == "Cellfone")
                {
                    if (exactList[kvp.Key])
                    {
                        if (kvp.Value.ToString() != "")
                            query += kvp.Key + " = '" + kvp.Value.ToString() + "'";
                    }
                    else
                    {
                        if (kvp.Value.ToString() != "")
                            query += kvp.Key + " LIKE '%" + kvp.Value.ToString() + "%'";
                    }
                }
                else if (kvp.Key == "CreatedTime" || kvp.Key == "Birthday")
                {
                    if (DateTime.Parse(kvp.Value.ToString()) != noValue)
                        query += kvp.Key + " = #" + kvp.Value.ToString() + "#";
                }
            }

            return query;
        }

        public static System.Object GetUser(Dictionary<String, System.Object> parametersList, Dictionary<String, bool> exactList, bool oneRow)
        {
            VietImageDataClassesDataContext _db = new VietImageDataClassesDataContext();
            String query = BuildQuery(parametersList, exactList);
            var v = _db.ExecuteQuery<User>(query);
            if (oneRow)
            {
                if (v.Count() == 0)
                    return null;
                return v.First();
            }
            if (v.Count() == 0)
                return null;
            return v.ToList();
        }
        #endregion
    }
}